/*
 * cache.h
 *
 *  Created on: Nov 19, 2013
 *      Author: adijoshi
 */

#ifndef CACHE_H_
#define CACHE_H_

#define SETS 16384
#define WAYS 8
#define BYTES_PER_LINE 64		// bytes
#define OUTPUT_ON 1				// 1 - print on console, 0 - send to text file
#define FILENAME "test_file.txt"

unsigned int TAG_BITS,INDEX_BITS,BYTE_OFFSET;

typedef struct CacheLineStruct{
	int Tag,LRU_Status,MESI_Status;
} CacheLine;

typedef enum LineStatusEnum{
	M,
	E,
	S,
	I
} LineStatus;

CacheLine L2Cache[SETS][WAYS];

void init_Cache();
void exec_Read_Req(unsigned int operation,unsigned int address);
void exec_Write_Req(unsigned int operation,unsigned int address);
void print_Output(char* operation, unsigned int address);
unsigned int extract_Index(unsigned int address);
unsigned int extract_Tag(unsigned int address);
unsigned int extract_Byte_Offset(unsigned int address);
int match_Tag(int set,unsigned int address);
LineStatus get_Line_Status(int set,int way);
void set_Line_Status(int set,int way,LineStatus nextStatus);
int get_Line_Tag(int set,int way);
void set_Line_Tag(int set,int way,int tag);
int get_Line_LRU(int set,int way);
void set_Line_LRU(int set,int way,int lruStatus);
int get_Snoop_Result(char operation,unsigned int address);
void put_Snoop_Result(char operation,unsigned int address);
void clear_Cache();
void print_Cache();
int fill_Cache_Line(int set,unsigned int address);
LineStatus update_MESI(unsigned int operation, int snoopResult, int set, int way);
void update_LRU(int set, int way);
int find_LRU_way(int set);

#define CPU_READ_D 0
#define CPU_WRITE_D 1
#define CPU_READ_I 2
#define SNOOPED_INVALIDATE 3
#define SNOOPED_READ 4
#define SNOOPED_WRITE 5
#define SNOOPED_RFO 6
#define CLEAR_CACHE 8
#define PRINT_CACHE 9

#define SNOOPED_MISS 0
#define SNOOPED_HIT 1

#endif /* CACHE_H_ */
